package g11.dao;

import g11.model.Employee;
import g11.model.WorkFor;

import java.util.ArrayList;
import java.util.List;

import org.apache.log4j.Logger;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;

public class WorkForDAOImpl implements WorkForDAO {

	private static final Logger log = Logger.getLogger(PatientDAOImpl.class);

	private Session session;

	public Session getSession() {
		return this.session;
	}

	public void cleanup() {
		if (session != null)
			session.close();
		// HibernateUtil.shutdown();
	}

	public WorkForDAOImpl() {

	}

	@Override
	public boolean checkWorkForRelation(Employee doctor, Employee staff)
			throws DAOException {
		this.session = HibernateUtil.getSessionFactory().openSession();
		List<WorkFor> workforList = new ArrayList<WorkFor>();
		Boolean isWorkFor = false;
		if (doctor == null || staff == null) {
			return isWorkFor;
		}
		try {
			Query q;

			q = session
					.createQuery("from WorkFor w where w.staffId = ? and w.doctorId=? ");

			q.setInteger(0, staff.getId());
			q.setInteger(1, doctor.getId());
			workforList = q.list();
			if (workforList.size() == 0) {
				// session.close();
				isWorkFor = false;
			}

			else
				isWorkFor = true;

		} catch (HibernateException e) {
			e.printStackTrace();
			throw new DAOException(e.getMessage());

		} finally {
			if (session.isOpen())
				session.close();
		}
		return isWorkFor;
	}

	public boolean checkWorkForRelation_old(Employee doctor, Employee staff)
			throws DAOException {
		this.session = HibernateUtil.getSessionFactory().openSession();
		List<Employee> staffList = new ArrayList<Employee>();
		Boolean isWorkFor = false;
		try {
			Query q;
			/*
			 * the "WorkFor" and "Employee" in the Query are actucally refer to
			 * the Model Class rather than the Table in the database,
			 * accrodingly, the attribute of them are the attribute in the
			 * class, not the attributes in the table.
			 */
			q = session
					.createQuery("select staff from WorkFor as w, Employee as staff where w.staffId = staff.id and w.doctorId=? ");
			/*
			 * setInteger used to refer to the "?" in the Query, "0" means as
			 * for the first "?"(the ? on the right hand side of "w.doctorId="),
			 * "doctor.getId()" is the variable used to place at that "?"
			 */
			q.setInteger(0, doctor.getId());
			staffList = q.list();
			if (staffList.size() == 0) {
				session.close();
				return isWorkFor;
			}

			else {
				for (int i = 0; i < staffList.size(); i++) {
					if (staffList.get(i).getId() == staff.getId()) {
						isWorkFor = true;
					}
				}
			}
		} catch (HibernateException e) {
			e.printStackTrace();
			throw new DAOException(e.getMessage());

		} finally {
			if (session.isOpen())
				session.close();
		}
		return isWorkFor;
	}

	@Override
	public void createWorkForRelation(Employee doctor, Employee staff)
			throws DAOException {
		this.session = HibernateUtil.getSessionFactory().openSession();
		WorkFor workfor = new WorkFor();
		workfor.setDoctorId(doctor.getId());
		workfor.setStaffId(staff.getId());
		Transaction tran = null;
		try {
			tran = session.beginTransaction();
			session.save(workfor);
			tran.commit();
		} catch (HibernateException e) {
			tran.rollback();
			throw new DAOException(e.getMessage());
		} finally {
			if (session.isOpen())
				session.close();
		}

	}

	@Override
	public void deleteWorkForRelation(Employee doctor, Employee staff)
			throws DAOException {
		this.session = HibernateUtil.getSessionFactory().openSession();
		WorkFor workfor = new WorkFor();
		workfor.setDoctorId(doctor.getId());
		workfor.setStaffId(staff.getId());
		Transaction tran = null;
		try {
			tran = session.beginTransaction();
			// using "merge" to solve: a different object with the same
			// identifier
			// value was already associated with the session
			workfor = (WorkFor) session.merge(workfor);
			session.delete(workfor);
			tran.commit();
		} catch (HibernateException e) {
			tran.rollback();
			throw new DAOException(e.getMessage());
		} finally {
			if (session.isOpen())
				session.close();
		}

	}

	@Override
	public List<Employee> getStaffList(Employee doctor) throws DAOException {
		List<Employee> staffList = new ArrayList<Employee>();
		this.session = HibernateUtil.getSessionFactory().openSession();
		try {
			Query q;
			q = session
					.createQuery("select staff from WorkFor as w, Employee as staff where w.staffId = staff.id and w.doctorId=? ");
			q.setInteger(0, doctor.getId());
			staffList = q.list();
		} catch (HibernateException e) {
			e.printStackTrace();
			throw new DAOException(e.getMessage());
		} finally {
			if (session.isOpen())
				session.close();
		}

		return staffList;

	}

	@Override
	public List<Employee> getDoctorList(Employee staff) throws DAOException {
		List<Employee> staffList = new ArrayList<Employee>();
		this.session = HibernateUtil.getSessionFactory().openSession();
		try {
			Query q;
			q = session
					.createQuery("select doctor from WorkFor as w, Employee as doctor where w.doctorId = doctor.id and w.staffId=? ");
			q.setInteger(0, staff.getId());
			staffList = q.list();
		} catch (HibernateException e) {
			e.printStackTrace();
			throw new DAOException(e.getMessage());
		} finally {
			if (session.isOpen())
				session.close();
		}

		return staffList;
	}

	@Override
	public void deleteWorkForRelationByWorkFor(WorkFor workFor)
			throws DAOException {
		this.session = HibernateUtil.getSessionFactory().openSession();
		Transaction tran = null;
		try {
			tran = session.beginTransaction();
			// using "merge" to solve: a different object with the same
			// identifier
			// value was already associated with the session
			workFor = (WorkFor) session.merge(workFor);
			session.delete(workFor);
			tran.commit();
		} catch (HibernateException e) {
			tran.rollback();
			throw new DAOException(e.getMessage());
		} finally {
			if (session.isOpen())
				session.close();
		}
	}
}
